<template>
	<view class="setting">
		<view class="kefu-box">
			<!-- 聊天内容 -->
			<scroll-view :scroll-y="true" id="scroll-view-content" class="scroll-h" :class="active ? 'scroll-h-icon' : ''"
				:show-scrollbar="true" :scroll-with-animation="true" :scroll-anchoring="true" refresher-background="#f5f5f5"
				:refresher-triggered="refreshTriggered" @scrolltolower="onRefresh"
				:scroll-into-view="'chat-item-'+scrollMsgIdx">
				<view v-for="(item, index) in chatList" :key="index" class="content"
					:style="{ flexDirection: item.isMe ? 'row-reverse' : '' }" :id="'chat-item-'+index">
					<!-- 头像 -->
					<image :src='item.avatar || defaultAvatar' mode="aspectFill" class="avatar-image">
					</image>
					<!-- 用户名称、消息时间 -->
					<view class="user-chat-info">
						<view class="user-info" :class="item.isMe ? 'order-2' : ''"
							:style="{ flexDirection: item.isMe ? 'row-reverse' : '' }">
							<view class="user-chat-name">
								{{ item.custName }}
							</view>
							<view class="online-time">
								{{ item.createTimeStr || '' }}
							</view>
						</view>
						<!-- 聊天消息 -->
						<view class="content-text" :style="{ textAlign: item.isMe ? 'right' : 'left' }">
							<view class="text-span">
								<u-parse :content="item.message"></u-parse>
							</view>
						</view>
					</view>
				</view>
				<view class="load-more" v-if="page <= totalPage" @click="onRefresh">查看更多消息</view>
			</scroll-view>
		</view>
		<!-- 底部发送信息 -->
		<view class="footerCon" :class="active ? 'on' : ''" :style="'transform: translate3d(0,' + percent + '%,0);'"
			ref="footerCon">
			<view class="footer row-bottom" ref="footer">
				<image style="width: 50upx;height: 50upx;" :src="active? 'https://www.ysrs.xyz/apiI/ll/file/preview/1744764386151ff80808195d597d901963c0fbb67002f.png'
					: 'https://www.ysrs.xyz/apiI/ll/file/preview/1744764256401ff80808195d597d901963c0dc091002e.png'
					" @click="emoticon" />

				<view style="margin-left: 30upx;">
					<uv-upload :maxCount="1" :previewFullImage="true" @afterRead="successImage" accept="all">
						<image src="https://www.ysrs.xyz/apiI/ll/file/preview/1744767500449ff80808195d597d901963c3f40a10031.png"
							mode="widthFix" style="width: 50upx;height: 50upx;"></image>
					</uv-upload>
				</view>

				<view class="footerConInput">
					<uv-input placeholder="请输入内容" border="surround" v-model="message" ref="input" @focus="focus"
						@confirm="sendTest('')"></uv-input>
				</view>

				<view class="send" @click="sendTest('')">
					发送
				</view>
			</view>
			<!-- 表情 -->
			<view class="bottom-icon" v-if="active">
				<Emotion @emotion="handleEmotion"></Emotion>
			</view>
		</view>
	</view>
</template>
<script>
	import Emotion from "./emotion.vue";
	import $emo from "./constEmo.js";


	export default {
		components: {
			Emotion,
		},
		data() {
			return {
				defaultAvatar: 'https://www.ysrs.xyz/apiI/ll/file/preview/1743090725920ff80808195d597d90195d84db4200013.png',
				active: false, //表情展示
				message: '', //输入信息
				userInfo: '', //用户信息
				chatList: [], //信息列表
				knowledgeInfo: '', //知识库
				agentUser: '', //缓存信息
				constData: this.$constData,
				page: 1,
				pageSize: 10,
				totalPage: -1, //总聊天记录页数
				freshing: false,
				// 超出限制数组
				model: 'product',
				pid: 1,
				percent: 0,
				refreshTriggered: true,
				isSocketOpen: false, //webscoket是否已经打开
				scrollMsgIdx: 0, // 滚动条定位为到哪条消息
				isMorePage: false, //是否多屏数据
				isSendKnowledge: false,
			};
		},

		onLoad(o) {
			this.info = JSON.parse(o.info)
			uni.setNavigationBarTitle({
				title: this.info.name
			})
			// 创建连接
			// console.log(this.wss()+'/api/kefu');
			this.connectSocket();

			//监听socket错误
			uni.onSocketError(() => {
				this.isSocketOpen = false;
			})

			//监听socket错误
			uni.onSocketClose(() => {
				this.isSocketOpen = false;
			})
			//监听服务器内容
			uni.onSocketMessage((res) => {
				console.log('收到服务器内容：', JSON.parse(res.data));
				this.getSocketData(JSON.parse(res.data))
			});

		},

		onUnload() {
			uni.closeSocket();
		},

		methods: {

			//连接scoket
			connectSocket() {
				let socket = uni.connectSocket({
					url: 'wss://mall.cn/api/kefu', //自己的链接地址
					success: (res => {

					}),
				});
				//监听
				socket.onOpen((res) => {
					this.isSocketOpen = true;
					this.hanldeSendSocketMessage(); //首次进入授权
				})
			},

			// 数据处理
			getSocketData(res) {
				if (res.code == 401) {
					this.hanldeSendSocketMessage();
					return
				}
				if (res.code != 200) return
				let data = res.data;
				//授权信息，留言，坐席繁忙将返回的坐席存在缓存数据
				if (res.code == 200 && ['auth', 'level_msg', 'agent_busy'].includes(data.messageType)) {
					this.agentUser = data;
				}
				//获取到正确的数据
				if (data.messageType) {
					switch (data.messageType) {
						case 'auth': // 建立连接，不做任何处理
							this.tips = '';
							break;
						case 'knowledge': // 首次进入获取知识库
							this.knowledgeInfo = data;
							this.addMessage(data); //获取知识库列表
							break;
						case 'query_msg_list': //获取消息列表
							this.loadMessageSuccess(data);
							break;
						case 'leave_msg': //留言
							this.addMessage(data.extra.content);
							break;
						case 'agent_busy': //坐席繁忙
							this.tips = data.extra.tips;
							this.addMessage(data.extra.content);
							break;
						default:
							this.addMessage(data);
							break;
					}
				}
			},

			//获取聊天消息的高度
			getChatHeight() {
				if (!this.isMorePage) {
					const query = uni.createSelectorQuery().in(this);
					query.select('#kefu-content').boundingClientRect(data => {
						if (data) {
							let systemInfo = uni.getStorageSync('systemInfo');
							let editHeight = this.active ? 380 : 65; //有表情框
							let toMoreHeight = 0;
							if (this.isSendKnowledge) { //点击知识库
								toMoreHeight = 60
							}
							let caHeight = Number(systemInfo.windowHeight) - Number(editHeight) - Number(data.height) -
								toMoreHeight;
							this.isMorePage = Number(caHeight) <= 0; //是否只有一屏//内容的高度大于可用窗口的高度-输入文字的高度
							this.isSendKnowledge = false;
						}
					}).exec();
				}
			},

			//添加消息
			addMessage(data) {
				//当前是客户还是坐席
				let isMe = data.sendType == 'CUST'; //如果是客服
				//客户，获取当前用户缓存中的数据
				let custName = "";
				let avatar = "";
				if (isMe) {
					custName = this.userInfo.nickname;
					avatar = this.userInfo.avatar;
				} else {
					custName = this.agentUser.content.custName;
					avatar = this.agentUser.content.avatar;
				}
				let params = {
					id: Math.random(),
					custName,
					message: data.message,
					createTimeStr: data.createTime,
					isMe, //是否是我发送
					avatar: avatar,
					messageType: data.messageType,
				};
				this.chatList.unshift(params);
				setTimeout(() => {
					this.$nextTick(() => {
						// 数据和DOM都更新完成后，获取容器高度
						this.getChatHeight();
					});
				}, 1000)
				setTimeout(() => {
					this.scrollToBottom();
				}, 100)

			},
			loadMessageSuccess(data) {
				this.refreshTriggered = false;
				//消息返回来的数据，进行处理
				// 如果返回的页数跟当前的页数相同，不做任何处理
				let list = data.content.list.map(item => {
					return {
						...item,
						isMe: item.sendType == 'CUST', //是否是自己
						avatar: item.isMe ? this.userInfo.avatar : ''
					}
				})
				list.forEach(v => v.avatar = v.isMe ? this.userInfo.avatar : '')
				this.chatList = this.chatList.concat(list);
				this.page += 1;
				this.totalPage = data.content.totalPage;
				setTimeout(() => {
					// 数据加载完成后更新数据状态
					this.$nextTick(() => {
						// 数据和DOM都更新完成后，获取容器高度
						this.getChatHeight();
					});
				}, 1000); // 假设数据加载需要1秒钟
			},


			scrollToBottom() {
				let size = this.chatList.length;
				if (size > 0) {
					this.scrollToMsgIdx(size - 1);
				}
			},

			scrollToMsgIdx(idx) {
				// 如果scrollMsgIdx值没变化，滚动条不会移动
				if (idx == this.scrollMsgIdx && idx > 0) {
					this.$nextTick(() => {
						// 先滚动到上一条
						this.scrollMsgIdx = idx - 1;
						// 再滚动目标位置
						this.scrollToMsgIdx(idx);
					});
					return;
				}
				this.$nextTick(() => {
					this.scrollMsgIdx = idx;
				});

			},

			//授权
			hanldeSendSocketMessage() {
				this.userInfo = JSON.parse(uni.getStorageSync('USER_INFO'));
				let params = {
					sendType: "CUST",
					messageType: "auth",
					content: {
						avatar: this.userInfo.avatar,
						custId: this.userInfo.uid,
						custName: this.userInfo.nickname
					}
				}
				this.handleSendSocketMessage(params)
			},

			focus() {
				this.active = false;
				this.getChatHeight();
			},


			//上传图片
			successImage(e) {
				uploadFile(e.file.url).then(res => {
					value.forEach(img => {
						let content = `<img src='${res.message}'" class="chat-image"></img>`;
						let data = {
							token: this.agentUser.token,
							messageType: 'text',
							content: {
								messageType: 'text',
								message: content
							}
						};
						this.handleSendSocketMessage(data)
					})
				})
			},

			//发送消息
			sendTest(message, flag) {
				this.isSendKnowledge = flag || false;
				if (!this.message && !message) {
					return uni.showToast({
						title: '消息为空',
						icon: 'none'
					})
				}
				if (!this.userInfo) {
					//不存在用户信息，退出登录
					// getLogout().then((res) => {
					// 	store.commit("LOGOUT");
					// 	// uni.clearStorageSync();
					// 	uni.reLaunch({
					// 		url: "/pages/index/index",
					// 	});
					// 	getApp().globalData.cartCounts = 0;
					// store.commit("LOGIN", {
					//   token: '',
					// });
					// store.commit("UPDATE_USERINFO", null);
					// store.commit("SETUID", null);
					// })
					return;
				}
				let content = message || this.message;
				let data = {
					token: this.agentUser.token,
					messageType: 'text',
					content: {
						messageType: 'text',
						message: content
					}
				};
				this.handleSendSocketMessage(data)
				setTimeout(() => {
					if (!message) {
						this.message = "";
					}
				}, 100 * 1);
			},

			//选择表情
			handleEmotion(i) {
				let word = i.replace(/#|;/gi, "");
				let index = $emo.list.indexOf(word);
				let content =
					`<img class="chat-emtion" src="https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/${index}.gif" align="middle">`;
				let data = {
					token: this.agentUser.token,
					messageType: 'text',
					content: {
						messageType: 'text',
						message: content
					}
				};
				this.handleSendSocketMessage(data)
				this.active = false;
			},
			//send 发送消息
			handleSendSocketMessage(data) {
				if (!this.isSocketOpen) { //暂未连接
					this.connectSocket();
					return;
				}
				uni.sendSocketMessage({
					data: JSON.stringify(data),
				});
			},

			emoticon() {
				this.active = !this.active;
				this.getChatHeight();
			},
			//切换用户或结束会话        
			sendSession(messageType) {
				//发送数据给服务端，标记
				if (!this.agentUser || !this.userInfo) {
					return;
				}
				let data = {
					sendType: 'CUST',
					messageType: messageType,
					agentId: this.agentUser.content.custId,
					custId: this.userInfo.uid,
					token: this.agentUser.token,
					content: {}
				}
				if (messageType == 'query_msg_list') { //加载消息列表
					data = Object.assign(data, {
						page: this.page,
						pageSize: this.pageSize
					})

				}
				this.handleSendSocketMessage(data, true)
			},
			// 自定义下拉刷新被触发
			onRefresh() {
				if (this.freshing) return;
				if (this.page > this.totalPage) {
					this.refreshTriggered = false
					return;
				}
				this.refreshTriggered = true;
				this.freshing = true;
				this.sendSession('query_msg_list');
				setTimeout(() => {
					this.freshing = false;
				}, 500);
			},
		},
	}
</script>

<style lang="scss">
	.scroll-h {
		max-height: 100%;
		padding-bottom: 20upx;
		overflow-anchor: auto;
		transform: rotate(180deg);
	}

	.autoHeight {
		height: calc(100% - 65px);
		overflow-y: auto;
	}

	.scroll-h-icon.autoHeight {
		height: calc(100% - 380px);
		overflow-y: auto;
	}


	.user-chat-info {
		flex: 1;
	}

	.user-info {
		margin-bottom: 10upx;
	}

	.order-2.user-info {
		text-align: right;
	}

	.setting {
		min-height: auto;
		background: #f5f5f5;
	}

	.kefu-box {
		padding: 0 20upx;
		height: 100vh;

		.content {
			transform: rotate(180deg);
			display: flex;
			// align-items: center;
			padding-bottom: 35upx;
		}

		.avatar-image {
			width: 60upx;
			height: 60upx;
			border-radius: 50%;
			margin: 10upx 10upx;
		}


		.content-text-knowledge {
			padding: 10upx 15upx;
			background-color: #fff !important;
			border-radius: 5px;
			margin-top: 10upx;
			position: relative;

			.knowledge-title {
				font-size: 28upx;
				font-weight: 550;
				margin-bottom: 20upx;
			}

			.border-none {
				:last-child {
					border: none !important;
				}

				.iconfont {
					font-size: 24upx !important;
				}
			}

			.knowledge-flxe {
				min-width: 60upx;
				max-width: 600upx;
				padding: 10px 0;
				display: flex;
				justify-content: space-between;
				align-items: center;
				cursor: pointer;
				border-bottom: 1px solid #f5f5f5;
				font-size: 24upx;
			}
		}

		.content-text {
			// background-color: #c7dcfa;
			margin-top: 10upx;
			position: relative;

			.text-span {
				max-width: 600upx;
				border-radius: 5px;
				padding: 10upx 15upx;
				display: inline-block;
				background-color: #c7dcfa;
				text-align: left;
			}

			.avatar-image {
				max-width: 300upx;
				max-height: 300upx;
			}
		}

		.online-time {
			color: #666;
			font-size: 20upx;
		}
	}



	.user-chat-name {
		color: #000;
	}

	.setting-item {
		padding: 25upx 20upx;
		border-bottom: 2upx #dfdfdf solid;
		font-size: 26upx;
	}

	.avatar {
		width: 60upx;
		height: 60upx;
		border-radius: 50%;
		overflow: hidden;
	}

	.item-value {
		color: #999999;
	}

	.send {
		width: 70upx;
		text-align: center;
		height: 60upx;
		line-height: 60upx;
		font-weight: bold;
	}

	.input {
		max-height: 150upx;
		overflow-y: auto;
		overflow-x: hidden;
		flex: 1;
		margin: 0 10upx;
		border-radius: 10upx;
		background-color: #e5e5e5;
		/* padding: 17upx 30upx; */
		height: 60upx;
		padding: 0 10upx;
	}

	.footer {
		width: 100%;
		background-color: #fff;
		padding: 17upx 26upx;
		display: flex;
		align-items: center;
	}

	.footer image {
		width: 61upx;
		height: 60upx;
		display: block;
	}

	.footerCon {
		position: fixed;
		bottom: 0upx;
		min-height: 100upx;
		width: 100%;
		transition: all 0.005s cubic-bezier(0.25, 0.5, 0.5, 0.9);
		background-color: #fff;
	}

	.footerCon .on {
		bottom: 300upx;
		transform: translate3d(0, 0, 0) !important;
	}

	.footerConInput {
		width: 430upx;
		margin: 0 30upx;
	}

	.bottom-icon {
		padding: 15upx;
	}

	.chat-image {
		max-width: 375upx !important;
	}

	.load-more {
		text-align: center;
		color: #1423fc;
		padding: 5px 0;
		transform: rotate(180deg);
	}
</style>